home *** CD-ROM | disk | FTP | other *** search
/ Internet Surfer 2.0 / Internet Surfer 2.0 (Wayzata Technology) (1996).iso / pc / textfile / faqs / lisp_faq / part5 < prev    next >
Encoding:
Internet Message Format  |  1992-12-26  |  12.4 KB

  1. Xref: bloom-picayune.mit.edu comp.lang.lisp:8753 comp.lang.clos:1593 news.answers:4563
  2. Path: bloom-picayune.mit.edu!enterpoop.mit.edu!spool.mu.edu!uunet!ogicse!das-news.harvard.edu!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!mkant
  3. From: mkant+@cs.cmu.edu (Mark Kantrowitz)
  4. Newsgroups: comp.lang.lisp,comp.lang.clos,news.answers
  5. Subject: FAQ: CLOS and PCL Questions 5/6 [Monthly posting]
  6. Summary: Questions about CLOS, PCL and object-oriented programming in Lisp
  7. Message-ID: <lisp-faq-5.text_724237355@cs.cmu.edu>
  8. Date: 13 Dec 92 09:03:06 GMT
  9. Article-I.D.: cs.lisp-faq-5.text_724237355
  10. Expires: Tue, 26 Jan 1993 09:02:35 GMT
  11. Sender: news@cs.cmu.edu (Usenet News System)
  12. Reply-To: lisp-faq@think.com
  13. Followup-To: poster
  14. Organization: School of Computer Science, Carnegie Mellon
  15. Lines: 237
  16. Approved: news-answers-request@MIT.Edu
  17. Supersedes: <lisp-faq-5.text_721645367@cs.cmu.edu>
  18. Nntp-Posting-Host: a.gp.cs.cmu.edu
  19.  
  20. Archive-name: lisp-faq/part5
  21. Last-Modified: Thu Nov  5 19:30:40 1992 by Mark Kantrowitz
  22. Version: 1.27
  23.  
  24. ;;; ****************************************************************
  25. ;;; Answers to Frequently Asked Questions about Lisp ***************
  26. ;;; ****************************************************************
  27. ;;; Written by Mark Kantrowitz and Barry Margolin
  28. ;;; lisp-faq-5.text -- 11959 bytes
  29.  
  30. This post contains Part 5 of the Lisp FAQ. It is cross-posted to the
  31. newsgroup comp.lang.clos because it contains material of interest to
  32. people concerned with CLOS, PCL and object-oriented programming in
  33. Lisp. The other parts of the Lisp FAQ are posted only to the
  34. newsgroups comp.lang.lisp and news.answers.
  35.  
  36. If you think of questions that are appropriate for this FAQ, or would
  37. like to improve an answer, please send email to us at lisp-faq@think.com.
  38.  
  39. CLOS/PCL Questions (Part 5):
  40.  
  41.   [5-0]   What is CLOS (PCL) and where can I get it?
  42.           How do you pronounce CLOS?
  43.   [5-1]   What documentation is available about object-oriented
  44.           programming in Lisp?  
  45.   [5-2]   How I write a function that can access defstruct slots by
  46.           name?  I would like to write something like 
  47.           (STRUCTURE-SLOT <object> '<slot-name>).   
  48.   [5-3]   How can I list all the CLOS instances in a class?
  49.   [5-4]   How can I store data and CLOS instances (with possibly circular
  50.           references) on disk so that they may be retrieved at some later
  51.           time?
  52.   [5-5]   Given the name of a class, how can I get the names of its slots?
  53.  
  54. Search for [#] to get to question number # quickly.
  55.  
  56. In general, questions about object oriented programming in Lisp,
  57. especially questions about using CLOS or compiling PCL, should be
  58. directed to the newsgroup comp.lang.clos.
  59.  
  60. ----------------------------------------------------------------
  61. [5-0]  What is CLOS (PCL) and where can I get it?
  62.        How do you pronounce CLOS?
  63.  
  64. CLOS (Common Lisp Object System) is the object-oriented programming
  65. standard for Common Lisp. It is the successor to Symbolics FLAVORS and
  66. Xerox LOOPS (Lisp Object Oriented Programming System). The acronym
  67. CLOS is pronouned either as "See-Loss" or "Closs", depending on taste.
  68. PCL (Portable Common Loops) is a portable CLOS implementation, and is
  69. available by anonymous ftp from parcftp.xerox.com (13.1.64.94) in the
  70. /pub/pcl/ directory. Also in the same directory are sources for CLX R5
  71. and an inspecter.
  72.  
  73. The sources for the CLOS Metaobject Protocol specification are
  74. also available from parcftp as /pub/pcl/mop/spec.tar.Z. See also the book
  75. ``The Art of the Metaobject Protocol'' below. The Closette files
  76. related to this book are available from parcftp as /pub/pcl/mop/closette.lisp.
  77.  
  78. ----------------------------------------------------------------
  79. [5-1] What documentation is available about object-oriented
  80.       programming in Lisp? 
  81.  
  82. Books about object-oriented programming in Lisp include:
  83.  
  84.    1. dpANS CL describes the entire Common Lisp language, which includes the
  85.       CLOS standard.  Informally, CLtL2 can also be used to learn about CLOS, 
  86.       but please remember that CLtL2 is not an official X3J13 committee
  87.       document. (The presentation of CLtL2 differs from that of the draft
  88.       proposed standard, and some matters of fact have changed in the proposed
  89.       standard since the publication of CLtL2.)
  90.  
  91.    2. Sonya E. Keene
  92.       "Object-Oriented Programming in Common Lisp: 
  93.        A Programmer's Guide to CLOS"
  94.       Addison-Wesley (Reading, MA), 1989. 266 pages. ISBN 0-201-17589-4.
  95.            Tutorial introduction to CLOS with many examples and
  96.            a lot of good advice for designing large programs using CLOS.
  97.  
  98.    3. Jo A. Lawless and Molly M. Miller.
  99.       "Understanding CLOS: the Common Lisp Object System"
  100.       Digital Press, 1991. 192 pages.
  101.  
  102.    4. Gregor Kiczales, Jim des Rivieres, and Daniel G. Bobrow.
  103.       "The Art of the Metaobject Protocol"
  104.       MIT Press, 1991. 335 pages. ISBN 0-262-61074-4
  105.            The first part of the book presents a model CLOS implementation,
  106.            introduces the basic principles of metaobject protocols, and 
  107.            works through the key elements of the CLOS Metaobject Protocol.
  108.            The second half is the detailed specification of the CLOS
  109.            Metaobject Protocol. A simple working interpreter suitable
  110.            for experimentation is contained in an appendix.
  111.  
  112.    5. Robert R. Kessler and Amy R. Petajan.
  113.       "LISP, Objects, and Symbolic Programming"
  114.       Scott, Foresman and Company (Glenview, IL), 1988. 644 pages.
  115.            Includes a small Lisp compiler.
  116. ----------------------------------------------------------------
  117. [5-2] How can I write a function that can access defstruct slots by name?  I
  118.       would like to write something like 
  119.         (STRUCTURE-SLOT <object> '<slot-name>).
  120.  
  121. There is currently no portable, built-in way to access structure slots
  122. given only the name.  If your Common Lisp includes an implementation
  123. of CLOS that supports the meta-object protocol specified in the
  124. original X3J13 draft spec (document X3J13/88-003), then it probably will
  125. allow (SLOT-VALUE <object> '<slot-name>); however, not all
  126. implementations of CLOS currently provide this.  Lacking this, some
  127. implementations may provide implementation-dependent functions that
  128. allow access to structure slots by name; note that this may cause
  129. saved images to be larger, as some implementations normally open-code
  130. structure accessors and discard slot name information.
  131.  
  132. While it is not possible to write a fully general STRUCTURE-SLOT function,
  133. it is not very difficult to write version that handles specific structure
  134. types.  For instance, after defining:
  135.  
  136.    (defstruct spaceship name captain position velocity)
  137.  
  138. one may then define:
  139.  
  140.    (defun spaceship-slot (spaceship slot-name)
  141.      (ecase slot-name
  142.        (name (spaceship-name spaceship))
  143.        (captain (spaceship-captain spaceship))
  144.        (position (spaceship-position spaceship))
  145.        (velocity (spaceship-velocity spaceship))))
  146.  
  147. or using CLOS (generic functions):
  148.  
  149. (defgeneric spaceship-slot (spaceship slot-name)
  150.   (:method ((x spaceship) (slot (eql :name)))
  151.     (spaceship-name x))
  152.   (:method ((x spaceship) (slot (eql :captain)))
  153.     (spaceship-captain x))
  154.   (:method ((x spaceship) (slot (eql :position)))
  155.     (spaceship-position x))
  156.   (:method ((x spaceship) (slot (eql :velocity)))
  157.     (spaceship-velocity x)))
  158.  
  159. Another popular way to define this is:
  160.  
  161.    (defun spaceship-slot (spaceship slot-name)
  162.      (funcall (symbol-function
  163.                 (find-symbol (format nil "SPACESHIP-~A" slot-name)
  164.                              #.(package-name *package*)))
  165.               spaceship))
  166.  
  167. I personally recommend the first version.  It is likely to be much faster
  168. and more memory efficient than the second version.  It's also easy to get
  169. the second one wrong; many people forget to specify the package argument to
  170. FIND-SYMBOL, which can cause incorrect results when the package at run time
  171. is different from the one at compile time.  Even my version assumes that
  172. SPACESHIP-SLOT is being defined in a file that is in the same package as
  173. the one containing the structure definition; if this isn't the case,
  174. #.(PACKAGE-NAME *PACKAGE*) should be replaced by a string naming the
  175. correct package.
  176.  
  177. Another workaround is to define a MY-DEFSTRUCT macro that parses the
  178. defstruct arguments and expands into a call to DEFSTRUCT along with a
  179. definition of the runtime slot-accessor function.
  180.  
  181. Some non-portable techniques include the use of LCL:STRUCTURE-REF
  182. in Lucid and EXCL:STRUCTURE-REF in Allegro.
  183. ----------------------------------------------------------------
  184. [5-3] How can I list all the CLOS instances in a class?
  185.  
  186. There is no built-in way to enumerate the instances of a class.  If you are
  187. only interested in listing the instances of classes that you have defined,
  188. it is not very difficult to implement it as part of your class definition.
  189. Add a shared slot, e.g. ALL-INSTANCES, with an initial value of NIL, to the
  190. class definition.  Then write an after-method on INITIALIZE-INSTANCE for
  191. this class, which pushes the instance being initialized onto ALL-INSTANCES.
  192. Note that this must be done separately for each class that wants to maintain
  193. such a list; it can't be encapsulated in a mixin class, because all its
  194. dependent classes would share the same ALL-INSTANCES slot.  A compromise
  195. would be to use a mixin to define the INITIALIZE-INSTANCE after-method (and
  196. any other general-purpose methods that use the slot), but not the shared
  197. slot; it would be up to the descendant classes to define the slot at the
  198. level of the class hierarchy that is appropriate. You could also try
  199. defining the classes that need instance-recording as instances of a
  200. metaclass that holds the instance registry on the class object. The
  201. recording behavior could then be built-in to an after method on
  202. initialize-instance for the root class of the metaclass, or even
  203. allocate-instance. To allow for garbage collection of old instances,
  204. you will also need to define a generic function to remove the recorded
  205. instances from the list of instances.
  206. ----------------------------------------------------------------
  207. [5-4]  How can I store data and CLOS instances (with possibly circular
  208.        references) on disk so that they may be retrieved at some later
  209.        time?
  210.  
  211. There are two main techniques of doing this kind of persistent object
  212. storage. The first involves using #. to compile the data into a file.
  213. The second produces an ASCII representation which, when evaluated,
  214. will reproduce an equivalent set of data.
  215.  
  216. If the data you wish to save is stored in the variable *hash-table*,
  217. create a file containing just the lines
  218.         (in-package "YOUR-PACKAGE")
  219.         (setq *hash-table* '#.*hash-table*)
  220. and compile it. The #. macro performs read-time evaluation of the
  221. expression following the dot, and so this compiles the data into the
  222. file. You may then load the file to restore the data. However, the
  223. resulting binary file is not portable between Lisp implementations,
  224. and sometimes not even for the same Lisp on different platforms. Also,
  225. some Lisps will treat the data as constant, and place it on pages in
  226. memory that are marked read-only (after it is loaded). If one tries to
  227. later modify the data, these Lisps will signal an error. Lucid CL only
  228. puts such constants in a read-only area when they appear inside
  229. functions, so this should be safe. Allegro CL doesn't seem to complain
  230. about modification if the data is a cons. DEC's VAXLisp, however, has
  231. problems with #. circular structures in .fas files.
  232.  
  233. The other technique is to produce an ASCII representation of the Lisp
  234. objects which may then be saved to a file. To reproduce the data, one
  235. can load (or compile and load) the file. This technique is portable
  236. between different Lisps and platforms. Unfortunately, the resulting
  237. data is not necessarily EQ to the original. Kerry Koitzsch's
  238. save-object.lisp package is included in the Lisp Utilities Repository,
  239. ftp.cs.cmu.edu:/afs/cs.cmu.edu/user/mkant/Public/Lisp-Utilities/.
  240. (Note: You must cd to this directory in one atomic operation, as some
  241. of the superior directories on the path are protected from access by
  242. an anonymous ftp.) The Lisp Utilities Repository is described in
  243. detail in the answer to question [6-1].
  244.  
  245. See also the discussion of MAKE-LOAD-FORM and MAKE-LOAD-FORM-SAVING-SLOTS 
  246. in CLtL2.
  247.  
  248. ----------------------------------------------------------------
  249. [5-5]   Given the name of a class, how can I get the names of its slots?     
  250.  
  251. (defun class-slot-names (class-name)
  252.   (mapcar #'clos:slot-definition-name
  253.           (clos:class-slots (find-class class-name))))
  254.  
  255. ----------------------------------------------------------------
  256. ;;; *EOF*
  257.